/**
    Copyright (C) 2012 Guido Ludwig

    This file is part of JATT.
	http://code.google.com/p/jatt/

    JATT is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package de.guidoludwig.test.jatt;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import junit.framework.TestCase;
import de.guidoludwig.jatt.JATT;
import de.guidoludwig.jatt.chain.JATTContext;
import de.guidoludwig.jatt.chain.commands.FolderScanCommand;
import de.guidoludwig.jatt.chain.commands.config.FolderScanConfig;
import de.guidoludwig.jatt.util.ImageInfo;
import de.guidoludwig.jatt.util.JATTUtil;

public abstract class JATTTestBase extends TestCase {

	protected static final Map<String, Integer> sizes = new HashMap<String, Integer>();
	static {
		sizes.put("folder-clouds-300.jpg", 300);
		sizes.put("folder-clouds-1000.jpg", 1000);
		sizes.put("folder-clouds-2000.jpg", 2000);
		sizes.put("folder-clouds-300.png", 300);
		sizes.put("folder-clouds-1000.png", 1000);
		sizes.put("folder-clouds-2000.png", 2000);
		sizes.put("folder-clouds-300.gif", 300);
		sizes.put("folder-clouds-1000.gif", 1000);
		sizes.put("folder-clouds-2000.gif", 2000);
		JATT.setOutputLevel(JATT.LEVEL_DEBUG);
	}

	private File testRoot;
	private JATTContext context;

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		testRoot = JATTUtil.createTempDirectory();
		testRoot.mkdir();
		unzip();

		initialize();
	}

	protected File getArtCandidate1000() {
		File candidate = null;
		for (ImageInfo f : getContext().getAlternativeImages()) {
			if (f.getWidth() == 1000) {
				candidate = f.getFile();
				break;
			}
		}
		return candidate;
	}

	@Override
	protected void tearDown() throws Exception {
		delete(testRoot);
		super.tearDown();
	}

	protected JATTContext getContext() {
		return context;
	}

	protected void initialize() throws Exception {
		File album = new File(testRoot, "Album1");
		assertTrue(album.isDirectory());
		assertTrue(album.exists());
		context = new JATTContext(album.getAbsolutePath());
		FolderScanConfig config = new FolderScanConfig();
		FolderScanCommand command = new FolderScanCommand();
		command.configure(config);
		command.execute(context);
	}


	private void unzip() throws IOException {
		Enumeration<? extends ZipEntry> entries;
		ZipFile zipFile;

		zipFile = new ZipFile("src/test/resources/resources.zip");
		entries = zipFile.entries();


		while (entries.hasMoreElements()) {
			ZipEntry entry = entries.nextElement();

			if (entry.isDirectory()) {
				// Assume directories are stored parents first then
				// children.
				System.err.println("Extracting directory: " + entry.getName());
				// This is not robust, just for demonstration purposes.
				File tempDir = new File(testRoot, entry.getName());
				tempDir.mkdir();
				continue;
			}

			System.err.println("Extracting file: " + entry.getName());
			File nf = new File(testRoot, entry.getName());
			copyInputStream(
					zipFile.getInputStream(entry),
					new BufferedOutputStream(new FileOutputStream(nf)));
		}

		zipFile.close();
	}

	private void copyInputStream(InputStream in, OutputStream out)
			throws IOException {
		byte[] buffer = new byte[1024];
		int len;

		while ((len = in.read(buffer)) >= 0)
			out.write(buffer, 0, len);

		in.close();
		out.close();
	}

	void delete(File f) throws IOException {
		  if (f.isDirectory()) {
		    for (File c : f.listFiles())
		      delete(c);
		  }
		  if (!f.delete())
		    throw new FileNotFoundException("Failed to delete file: " + f);
		}


}
